/*
 * filename: CommonConfig.scala
 * description: 常用的设定
 */
package XunChunCPU.common
import chisel3.util._
import chisel3._
import XunChunCPU.common.Bundles._
// 寄存器相关特性
trait RegConfig {
    val regLen = 32
    val regAddrLen = 5
    val regNum = 32
}

// 指令映射
trait InstrConfig {
    val instrLen = 32
    val offsetLen = 16
    val instrAddrImmLen = 26
    val instrAddrLen = 32
    val immLen = 16
    //                        |op   |rs  |rt  |rd  |sa  |op2  
    def SW          = BitPat("b101011??????????????????????????")//
    def SB          = BitPat("b101000??????????????????????????")//
    def LW          = BitPat("b100011??????????????????????????")//
    def LB          = BitPat("b100000??????????????????????????")//
    def JALR        = BitPat("b000000?????00000?????00000001001")
    def JR          = BitPat("b000000?????000000000000000001000")
    def JAL         = BitPat("b000011??????????????????????????")
    def J           = BitPat("b000010??????????????????????????")
    def BLTZ        = BitPat("b000001?????00000????????????????")
    def BLEZ        = BitPat("b000110?????00000????????????????")
    def BGTZ        = BitPat("b000111?????00000????????????????")
    def BGEZ        = BitPat("b000001?????00001????????????????")//
    def BNE         = BitPat("b000101??????????????????????????")//
    def BEQ         = BitPat("b000100??????????????????????????")//
    // 移位指令
    def SRL         = BitPat("b00000000000???????????????000010")
    def SRA         = BitPat("b00000000000???????????????000011")
    def SRLV        = BitPat("b000000???????????????00000000110")
    def SRAV        = BitPat("b000000???????????????00000000111")//
    def SLL         = BitPat("b00000000000???????????????000000")
    def SLLV        = BitPat("b000000???????????????00000000100")
    // 逻辑指令
    def XORI        = BitPat("b001110??????????????????????????")
    def XOR         = BitPat("b000000???????????????00000100110")//
    def ORI         = BitPat("b001101??????????????????????????")//
    def OR          = BitPat("b000000???????????????00000100101")//
    def LUI         = BitPat("b00111100000?????????????????????")//
    def ANDI        = BitPat("b001100??????????????????????????")//
    def AND         = BitPat("b000000???????????????00000100100")
    // 算术运算指令
    def MUL         = BitPat("b011100???????????????00000000010")
    def SLT         = BitPat("b000000???????????????00000101010")//
    def SUB         = BitPat("b000000???????????????00000100010")
    def ADDIU       = BitPat("b001001??????????????????????????")//
    def ADDU        = BitPat("b000000???????????????00000100001")//
    def ADD         = BitPat("b000000???????????????00000100000")
    def ADDI        = BitPat("b001000??????????????????????????")


    // List

}

trait OPConfig {
    val OP_NOP      = 0.U
    val OP_ADD      = 1.U
    val OP_ADDU     = 2.U
    val OP_SUB      = 3.U
    val OP_SLT      = 4.U
    val OP_MUL      = 5.U
    val OP_AND      = 6.U
    val OP_LUI      = 7.U
    val OP_OR       = 8.U
    val OP_XOR      = 9.U
    val OP_SLL      = 10.U
    val OP_SRA      = 11.U
    val OP_SRL      = 12.U
    val OP_BEQ      = 13.U
    val OP_BNE      = 14.U
    val OP_BGEZ     = 15.U
    val OP_BGTZ     = 16.U
    val OP_BLEZ     = 17.U
    val OP_BLTZ     = 18.U
    val OP_J        = 19.U
    val OP_JAL      = 20.U
    val OP_JALR     = 21.U
    val OP_JR       = 22.U
    val OP_LB       = 23.U
    val OP_LW       = 24.U
    val OP_SB       = 25.U
    val OP_SW       = 26.U


    val BranchOrJump = OP_BEQ :: OP_BNE :: OP_BGEZ :: OP_BGTZ :: OP_BLEZ :: OP_BLTZ :: OP_J :: OP_JAL ::OP_JALR :: OP_JR :: Nil
}
trait MemConfig {
    val MemLB = 0.U
    val MemLW = 1.U
    val MemSB = 2.U
    val MemSW = 3.U
    val MemNothing = 4.U
}
trait ExeConfig{
    val NoException = 0.U
    val IntegerOverflow = 1.U
    val AddressError = 2.U
}
object CommonConfig 
    extends RegConfig 
    with ControlConfig
    with OPConfig
    with MemConfig
    with ExeConfig
    with InstrConfig{
        val memSize = 32
        def isBranchOrJump(op : UInt) : Bool = BranchOrJump.foldLeft(false.B){(r,e) => r || (e === op)}
        val NPC_4 = true.B
        val NPC_J = false.B
        val RamReadEnable = true.B
        val RamReadDisable = false.B
        val OneByte = true.B
        val OneWord = false.B
    }